﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LocationsController.cs" company="DissingNellemann">
//   
// All rights reserved </copyright>
// <summary>
//   The locations controller.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Website.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;

    using Website.CRUDServices;
    using Website.Models;
    using Website.Models.Styling;
    using Website.Models.ViewModels;

    using Location = Website.Models.Domain.Location;

    /// <summary>
    ///     The locations controller.
    /// </summary>
    [Authorize(Roles = "User, Admin")]
    public class LocationsController : BaseController
    {
        // GET: /Locations/
        #region Public Methods and Operators

        /// <summary>
        ///     The create location.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult CreateLocation()
        {
            this.ViewData["Regions"] = PrimitiveTypes.GetRegions();
            return this.View();
        }

        /// <summary>
        /// The create location.
        /// </summary>
        /// <param name="location">
        /// The location.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        [HttpPost]
        public ActionResult CreateLocation(Location location)
        {
            this.ViewData["Regions"] = PrimitiveTypes.GetRegions();

            if (!this.ModelState.IsValid)
            {
                return this.PartialView("_CreateLocationPartial", location);
            }

            this.PersistNewLocation(location);

            return this.RedirectToAction("Index");
        }

        /// <summary>
        /// The create location json.
        /// </summary>
        /// <param name="location">
        /// The location.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        public ActionResult CreateLocationJson(Location location)
        {
            this.ViewData["Regions"] = PrimitiveTypes.GetRegions();

            if (!this.ModelState.IsValid)
            {
                return this.PartialView("_CreateLocationPartial", location);
            }

            Guid newLocationID = this.PersistNewLocation(location);

            return this.Json(
                new { success = true, locationID = newLocationID.ToString(), locationName = location.Name });
        }

        /// <summary>
        /// The index.
        /// </summary>
        /// <param name="skip">
        /// The skip.
        /// </param>
        /// <param name="take">
        /// The take.
        /// </param>
        /// <param name="orderBy">
        /// The order by.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        public ActionResult Index(int? skip, int? take, string orderBy)
        {
            this.Init("Profiles");

            var locView = new LocationsView
            {
                Skip = skip ?? 0,
                Take = take ?? 20
            };

            var headerItems = new List<TableViewHeaderItem>();
            var item1 = new TableViewHeaderItem { Text = "Navn", SortableName = "Name", IsSortable = true };
            var item2 = new TableViewHeaderItem { Text = "Region", SortableName = "Region.Name", IsSortable = true };
            var item3 = new TableViewHeaderItem { Text = "PostNr.", SortableName = "Address.Zip", IsSortable = true };
            var item4 = new TableViewHeaderItem { Text = "By", SortableName = "Address.City", IsSortable = true };
            var item5 = new TableViewHeaderItem
            {
                Text = "Gade",
                SortableName = "Address.StreetName",
                IsSortable = true
            };
            var item6 = new TableViewHeaderItem { Text = "Att", SortableName = "Address.Att", IsSortable = true };
            headerItems.Add(item1);
            headerItems.Add(item2);
            headerItems.Add(item3);
            headerItems.Add(item4);
            headerItems.Add(item5);
            headerItems.Add(item6);

            locView.TableHeader = TableViewHeader.GetTableHeader("Index", 20, orderBy, headerItems, true);

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var query = new LocationsQuery();
                    query.Settings = new SearchSettings
                    {
                        OrderBy = orderBy,
                        Skip = locView.Skip,
                        Take = locView.Take
                    };

                    var res = (LocationsResult)client.Query(query);
                    if (res.List.Count() > 0)
                    {
                        foreach (CRUDServices.Location dto in res.List)
                        {
                            if (dto != null)
                            {
                                locView.Locations.Add(Location.Convert(dto));
                            }
                        }
                    }

                    locView.TotalLocations = res.TotalRowCount;
                });

            return View(locView);
        }

        /// <summary>
        /// The update location.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        public ActionResult UpdateLocation(Guid id)
        {
            this.ViewData["Regions"] = PrimitiveTypes.GetRegions();

            Location loc = null;

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var query = new LocationsQuery { Settings = new SearchSettings { IDEquals = id } };

                    var res = (LocationsResult)client.Query(query);

                    if (res.List.Any())
                    {
                        loc = Location.Convert(res.List[0]);
                    }
                });
            if (loc == null)
            {
                return this.RedirectToAction("Index");
            }

            if (loc.Region != null)
            {
                loc.RegionID = loc.Region.ID;
            }

            return View(loc);
        }

        #endregion

        #region Methods

        /// <summary>
        /// The persist new location.
        /// </summary>
        /// <param name="location">
        /// The location.
        /// </param>
        /// <returns>
        /// The <see cref="Guid"/>.
        /// </returns>
        private Guid PersistNewLocation(Location location)
        {
            Guid newLocationID = Guid.Empty;
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cmd = new CreateLocationCommand();

                    var addr = new Address
                    {
                        ID = Guid.NewGuid(),
                        Att = location.Address.Att,
                        City = location.Address.City,
                        StreetName = location.Address.StreetName,
                        StreetNr = location.Address.StreetNr,
                        Zip = location.Address.Zip
                    };

                    var reg = new Region { ID = location.RegionID };

                    cmd.NewLocation = new CRUDServices.Location
                    {
                        ID = Guid.NewGuid(),
                        Name = location.Name,
                        Within150Km = location.Within150Km,
                        Address = addr,
                        Region = reg
                    };

                    client.ExecuteCommand(cmd);

                    newLocationID = cmd.NewLocation.ID;
                });

            return newLocationID;
        }

        #endregion
    }
}